import React, { useCallback, useMemo, useState, useContext } from 'react';
import { Spin, Button, Modal, Table, Form, Tooltip, message } from 'antd';
import { uniqueId, size, trim, zipObject, fill, defaults, last } from 'lodash';
import classNames from 'classnames';

import BizIcon from '@/components/BizIcon';
import salaryStyle from '@/pages/SalaryManage/salaryManage.less';
import { useDynamicList } from '@/hooks';

import { BaseSettingContext } from '@/pages/SalaryManage/constant/BaseSettingContext';
import { shgFundsService } from '@/services/salaryManage/salaryCalculateService';
import { isSuccess } from '@/utils/request';
import { NumberSettingInput } from '@/pages/SalaryManage/components/NumberSettingInput';
import SignSelect, { LE, LT } from '../components/SignSelect';
import util from './util';
import style from './index.less';

const TipItem = ({ messageArray, children }) => (
    <div className={style.tipItem}>
        <div className={style.content}>{children}</div>
        <div className={style.tip}>{messageArray.join(',')}</div>
    </div>
);

const tableColumns = ({ handleDelete, onlyUpdate, decimalPlaces, handleRowUpdate, validateField }) => {
    const rel = [
        {
            title: '雇员该自然月薪资总额',
            dataIndex: 'vv_month_amount',
            width: 400,
            render(text, record, index) {
                const errorFieldMap = record?.vvValidateInfo?.errorFieldMap || {};
                const messageArray = record?.vvValidateInfo?.tipMap?.tipAmtRange || [];

                return (
                    <TipItem messageArray={messageArray}>
                        <div className={style.rangeBox}>
                            <NumberSettingInput
                                value={record.twStartAmt}
                                onChange={value => handleRowUpdate('twStartAmt', value, index, record)}
                                onBlur={util.delayExecute(() =>
                                    validateField(['twStartAmt', 'twEndAmt'], index, 'tipAmtRange')
                                )}
                                className={classNames(style.start, {
                                    [style.error]: !!errorFieldMap?.twStartAmt
                                })}
                                prefix="$"
                                placeholder="最小值"
                                style={{ width: 100 }}
                                nonNegative
                                decimalPlaces={decimalPlaces}
                            />

                            <SignSelect
                                value={record.twStartAmtSign}
                                onChange={value => handleRowUpdate('twStartAmtSign', value, index, record)}
                            />

                            <span>薪资总额</span>

                            <SignSelect
                                value={record.twEndAmtSign}
                                onChange={value => handleRowUpdate('twEndAmtSign', value, index, record)}
                            />

                            <NumberSettingInput
                                value={record.twEndAmt}
                                onChange={value => handleRowUpdate('twEndAmt', value, index, record)}
                                onBlur={util.delayExecute(() =>
                                    validateField(['twStartAmt', 'twEndAmt'], index, 'tipAmtRange')
                                )}
                                className={classNames(style.end, {
                                    [style.error]: !!errorFieldMap?.twEndAmt
                                })}
                                prefix="$"
                                placeholder="最大值"
                                style={{ width: 100 }}
                                nonNegative
                                decimalPlaces={decimalPlaces}
                            />
                        </div>
                    </TipItem>
                );
            }
        },
        {
            title: '雇员扣除额',
            dataIndex: 'shgAmt',
            width: 180,
            render(text, record, index) {
                const errorFieldMap = record?.vvValidateInfo?.errorFieldMap || {};
                const messageArray = record?.vvValidateInfo?.tipMap?.tipShgAmt || [];

                return (
                    <TipItem messageArray={messageArray}>
                        <div className={style.rangeBox}>
                            <NumberSettingInput
                                value={record.shgAmt}
                                className={classNames(style.start, {
                                    [style.error]: !!errorFieldMap?.shgAmt
                                })}
                                onChange={value => handleRowUpdate('shgAmt', value, index, record)}
                                onBlur={util.delayExecute(() => validateField(['shgAmt'], index, 'tipShgAmt'))}
                                placeholder="请输入"
                                prefix="$"
                                style={{ width: 100 }}
                                nonNegative
                                decimalPlaces={decimalPlaces}
                            />
                        </div>
                    </TipItem>
                );
            }
        }
    ];

    if (!onlyUpdate) {
        rel.push({
            title: '操作',
            dataIndex: 'v_operate',
            render(text, record) {
                return (
                    <Tooltip title="删除">
                        <Button
                            className={salaryStyle.operateIcon}
                            onClick={() => {
                                Modal.confirm({
                                    title: '确定删除',
                                    content: '确定要删除吗',
                                    okText: '确定',
                                    cancelText: '取消',
                                    onOk() {
                                        handleDelete(record.key);
                                    }
                                });
                            }}
                        >
                            <BizIcon type="DeleteIcon" />
                        </Button>
                    </Tooltip>
                );
            }
        });
    }
    return rel;
};

const validateRow = (row, validateFields) => {
    const tipMap = {};
    const errorFieldMap = {};

    const addMessageTip = (warnField, warnMessage) => {
        if (!tipMap[warnField]) {
            tipMap[warnField] = [];
        }
        tipMap[warnField].push(warnMessage);
    };

    // 1. 单个字段校验
    if (util.needValidate('shgAmt', validateFields) && !trim(row.shgAmt)) {
        errorFieldMap.shgAmt = true;
        addMessageTip('tipShgAmt', '请填选雇员扣除额!');
    }

    // 2.多个字段连合校验
    if (util.needValidate(['twStartAmt', 'twEndAmt'], validateFields) && !trim(row.twStartAmt) && !trim(row.twEndAmt)) {
        errorFieldMap.twStartAmt = true;
        errorFieldMap.twEndAmt = true;
        addMessageTip('tipAmtRange', '雇员该自然月薪资总额起始值与结束值至少填一个!');
    }

    if (
        util.needValidate(['twStartAmt', 'twEndAmt'], validateFields) &&
        trim(row.twStartAmt) &&
        trim(row.twEndAmt) &&
        row.twStartAmt > row.twEndAmt
    ) {
        errorFieldMap.twStartAmt = true;
        errorFieldMap.twEndAmt = true;
        addMessageTip('tipAmtRange', '雇员该自然月薪资总额起始值不能大于结束值!');
    }
    return { tipMap, errorFieldMap };
};

/**
 * 添加校验信息
 * @param {Array | Object} rows
 * @param {Array | Object } validateFields
 * @returns {(*&{validateInfo: {errorField, message}})|*}
 */
const addValidateInfo = (rows, validateFields) =>
    util.mapRows(rows, row => ({ vvValidateInfo: validateRow(row, validateFields) }));

const DetailModal = ({ model, visible, onCancel, onOk, onlyUpdate }) => {
    const [loading, setLoading] = useState(false);
    const { list: dataSource, resetList: resetDataSource, push, replace, remove } = useDynamicList([]);

    const {
        baseSetting: { scale: decimalPlaces }
    } = useContext(BaseSettingContext);

    const handleAdd = () => {
        const newItem = {
            v_id: uniqueId('id'),
            shgFundId: '',
            twStartAmt: null,
            twStartAmtSign: LT.value,
            twEndAmtSign: LE.value,
            twEndAmt: null,
            shgAmt: null
        };

        if (size(dataSource) === 0) {
            push(newItem);
            return;
        }

        // 取出最后一条数据
        const { twEndAmt, twEndAmtSign } = last(dataSource);
        if (trim(twEndAmt)) {
            // 如果最后一条数据存在最大值
            Object.assign(newItem, {
                twStartAmt: twEndAmt,
                twStartAmtSign: LT.value === twEndAmtSign ? LE.value : LT.value,
                twEndAmtSign,
                twEndAmt: null
            });
        }
        push(newItem);
    };

    const handleDelete = useCallback(
        (record, index) => {
            remove(index);
        },
        [remove]
    );

    const handleRowUpdate = useCallback(
        (field, fieldValue, index) => {
            const newRecord = { ...dataSource[index], [field]: fieldValue };
            replace(index, newRecord);
        },
        [dataSource, replace]
    );

    const validateField = useCallback(
        (fields, index, tipRangeField, row) => {
            const record = row || dataSource[index];
            const oldValidateInfo = record.vvValidateInfo || { tipMap: {}, errorFieldMap: {} };
            const defaultValidateInfo = {
                errorFieldMap: zipObject(fields, fill(Array(fields), false)),
                tipMap: tipRangeField ? { [tipRangeField]: [] } : zipObject(fields, fill(Array(fields), []))
            };
            const validateInfo = validateRow(record, fields);
            const newValidateInfo = {
                errorFieldMap: defaults(validateInfo.errorFieldMap, defaultValidateInfo.errorFieldMap),
                tipMap: defaults(validateInfo.tipMap, defaultValidateInfo.tipMap)
            };
            const mergeValidateInfo = {
                tipMap: { ...oldValidateInfo.tipMap, ...newValidateInfo.tipMap },
                errorFieldMap: { ...oldValidateInfo.errorFieldMap, ...newValidateInfo.errorFieldMap }
            };
            const newRecord = { ...record, vvValidateInfo: mergeValidateInfo };
            replace(index, newRecord);
        },
        [dataSource, replace]
    );

    const handleOnOk = () => {
        const newDataSource = addValidateInfo(dataSource);
        resetDataSource(newDataSource);

        if (size(newDataSource) === 0) {
            message.error('请添加数据');
            return;
        }

        const hasError = data => size(Object.keys((data.vvValidateInfo || { tipMap: {} }).tipMap || {})) > 0;
        // 如果校验不通过
        if (newDataSource.find(data => hasError(data))) {
            message.error('请正确填写信息');
            return;
        }

        setLoading(true);
        let reqParam = null;
        let savePromise = null;
        if (model.id) {
            // 编辑
            reqParam = newDataSource.map(item => ({ ...item, id: model.id, shgFundId: model.shgFundId }));
            savePromise = shgFundsService.updateShgDetail(reqParam[0]);
        } else {
            // 新增
            reqParam = newDataSource.map(item => ({ ...item, id: '', shgFundId: model.shgFundId }));
            savePromise = shgFundsService.addShgDetail(reqParam);
        }

        savePromise
            .then(res => {
                setLoading(false);
                if (isSuccess(res)) {
                    message.success('保存成功！');
                    onOk();
                } else {
                    message.error(res.msg);
                }
            })
            .catch(() => {
                setLoading(false);
            });
    };

    const columns = useMemo(
        () => tableColumns({ handleRowUpdate, handleDelete, onlyUpdate, decimalPlaces, validateField }),
        [handleRowUpdate, handleDelete, onlyUpdate, validateField]
    );

    useMemo(() => {
        if (model.id) {
            resetDataSource([model]);
        } else {
            handleAdd();
        }
    }, [model]);

    return (
        <Spin spinning={loading}>
            <Modal
                title={model.id ? '编辑' : '新增'}
                visible={visible}
                width="700px"
                onCancel={onCancel}
                onOk={handleOnOk}
                style={{ top: 50 }}
                destroyOnClose
            >
                <Form layout="inline" className={style.detailModal}>
                    <Table
                        rowKey={model.id ? 'id' : 'v_id'}
                        columns={columns}
                        dataSource={dataSource}
                        pagination={false}
                        scroll={{ x: 'max-content' }}
                        bordered
                        className={style.detailTable}
                    />
                    {model.id ? null : (
                        <Button type="dashed" block onClick={handleAdd} style={{ marginTop: 16, marginBottom: 32 }}>
                            + 添加
                        </Button>
                    )}
                </Form>
            </Modal>
        </Spin>
    );
};
DetailModal.defaultProps = {
    title: '新增',
    model: [],
    onCancel: () => {},
    onOk: () => {},
    onlyUpdate: false
};

export default Form.create({})(DetailModal);
